/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package genetic;

import java.util.ArrayList;
import java.util.Collections;
import reader.Data;
import reader.Header;

/**
 *
 * @author Ifun
 */
public final class Individual implements Comparable<Individual> {
    int fitnessVal = -1;
    int probability;
    ArrayList<Chromosome> gen;
    
    public Individual()
    {
        gen = new ArrayList<Chromosome>();
    }
    
    public Individual(int num, Header listAtribut)
    {
        gen = generateRandIndividual(num, listAtribut);
    }
    
    public int compareTo(Individual friend)
    {
        if(this.fitnessVal == friend.fitnessVal)
            return 0;
        else if(this.fitnessVal > friend.fitnessVal)
            return -1;
        else
            return 1;
    }
    
    public ArrayList<Chromosome> generateRandIndividual(int num, Header listAtribut)
    {
        ArrayList<Chromosome> genRand = new ArrayList<Chromosome>();
        ArrayList<String> container = new ArrayList<String>();

        while(genRand.size()<num)
        {
            Chromosome dna = new Chromosome(listAtribut);
            if(!container.contains(dna.content))
            {
                container.add(dna.content);
                genRand.add(dna);
            }
        }
        
        return genRand;
    }
    
    public Individual[] createChilds(Individual mother)
    {
        Individual father = this;
        Collections.sort(father.gen);
        
        Collections.sort(mother.getArrayChromosome(),Collections.reverseOrder());
        
        Individual[] childs = new Individual[2];
        childs[0] = new Individual();
        childs[1] = new Individual();
        for(int i = 0; i<this.gen.size();++i)
        {
            Chromosome[] childsChrom = new Chromosome[2];
            childsChrom[0] = new Chromosome();
            childsChrom[1] = new Chromosome();
            childsChrom = father.gen.get(i).crossOverChrom(father.gen.get(i), mother.gen.get(i));
            childs[0].gen.add(childsChrom[0]);
            childs[1].gen.add(childsChrom[1]);
        }
        
        return childs;
    }
    
    public void mutationIndividual()
    {
        int mutanNum = genMath.getRandomInt(this.gen.size());
        this.gen.get(mutanNum).mutasiChrom();
        this.fitnessVal = -1;
    }
    
    public void calculateFitness(Data data) throws Exception
    {
        int sum = 0;
        int ndata = 0;
        for(int i=0;i<gen.size();++i)
        {
            ndata = data.getJumlahDataSama(gen.get(i).content);
            sum += ndata;
            gen.get(i).setNFit(ndata);
        }
        fitnessVal = sum;
    }
    
    public int getFitness()
    {
        return fitnessVal;
    }
    
    public int getProbability()
    {
        return probability;
    }
    
    public void setProbability(int sumFitness)
    {
        probability =  (int)(this.fitnessVal*100/sumFitness);
    }
    
    public ArrayList<Chromosome> getArrayChromosome()
    {
        return gen;
    }
    
    public ArrayList<Chromosome> getRankedChromosome()
    {
        Collections.sort(this.gen);
        return gen;
    }
}
